Bug 450716 – New API to change global IM
authorMatthias Clasen <matthiasc@src.gnome.org>
Tue, 13 Jan 2009 19:15:42 +0000 (19:15 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Tue, 13 Jan 2009 19:15:42 +0000 (19:15 +0000)
        Requested by Daniel Elstner.

        * gtk/gtk.symbols:
        * gtk/gtkimmulticontext.[hc] (gtk_im_multicontext_set_context_id):
        New function to set the context id on a GtkIMMulticontext.

        * gtk/gtkentry.c:
        * gtk/gtktextview.c: Add a ::im-module property that can be
        set to override the global setting for the im module to be used.

svn path=/trunk/; revision=22113

ChangeLog
gtk/gtk.symbols
gtk/gtkentry.c
gtk/gtkimmulticontext.c
gtk/gtkimmulticontext.h
gtk/gtktextview.c

index 560992980e000ad27a515860c0773f0f32c06d03..56db91fba136069ed50ebdd2969dbf5676b80851 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2009-01-13  Matthias Clasen  <mclasen@redhat.com>
+
+       Bug 450716 – New API to change global IM
+
+       Requested by Daniel Elstner.
+
+       * gtk/gtk.symbols:
+       * gtk/gtkimmulticontext.[hc] (gtk_im_multicontext_set_context_id):
+       New function to set the context id on a GtkIMMulticontext.
+
+       * gtk/gtkentry.c:
+       * gtk/gtktextview.c: Add a ::im-module property that can be
+       set to override the global setting for the im module to be used.
+
 2009-01-13  Christian Dywan  <christian@imendio.com>
 
        Bug 566532 – GtkScaleButton implementation of GtkOrientable
index 029b6136e5535c0e64742caefccc566e6c6567d8..7e7d6f84f555f306a390562a3999b4a8899d65e8 100644 (file)
@@ -2060,6 +2060,7 @@ gtk_im_context_simple_new
 #if IN_FILE(__GTK_IM_MULTICONTEXT_C__)
 gtk_im_multicontext_append_menuitems
 gtk_im_multicontext_get_context_id
+gtk_im_multicontext_set_context_id
 gtk_im_multicontext_get_type G_GNUC_CONST
 gtk_im_multicontext_new
 #endif
index 5db98af14a36015159b9985fc7634267477943b9..c8c14e6534f24c77a5140a0abf2e370a84c37224 100644 (file)
@@ -140,6 +140,8 @@ struct _GtkEntryPrivate
   gint icon_margin;
   gint start_x;
   gint start_y;
+
+  gchar *im_module;
 };
 
 typedef struct _GtkEntryPasswordHint GtkEntryPasswordHint;
@@ -213,7 +215,8 @@ enum {
   PROP_ACTIVATABLE_PRIMARY,
   PROP_ACTIVATABLE_SECONDARY,
   PROP_SENSITIVE_PRIMARY,
-  PROP_SENSITIVE_SECONDARY
+  PROP_SENSITIVE_SECONDARY,
+  PROP_IM_MODULE
 };
 
 static guint signals[LAST_SIGNAL] = { 0 };
@@ -1083,6 +1086,24 @@ gtk_entry_class_init (GtkEntryClass *class)
                                                          TRUE,
                                                          GTK_PARAM_READWRITE));
   
+  /**
+   * GtkEntry:im-module:
+   *
+   * Which IM module should be used for this entry.
+   * 
+   * Setting this to a non-%NULL value overrides the
+   * system-wide IM module setting. See #GtkSettings:gtk-im-module
+   *
+   * Since: 2.16
+   */  
+  g_object_class_install_property (gobject_class,
+                                   PROP_IM_MODULE,
+                                   g_param_spec_string ("im-module",
+                                                        P_("IM module"),
+                                                        P_("Which IM module should be used"),
+                                                        NULL,
+                                                        GTK_PARAM_READWRITE));
+
   /**
    * GtkEntry:prelight:
    *
@@ -1783,6 +1804,13 @@ gtk_entry_set_property (GObject         *object,
                                     g_value_get_boolean (value));
       break;
 
+    case PROP_IM_MODULE:
+      g_free (priv->im_module);
+      priv->im_module = g_strdup (g_value_get_string (value));
+      if (GTK_IS_IM_MULTICONTEXT (entry->im_context))
+        gtk_im_multicontext_set_context_id (GTK_IM_MULTICONTEXT (entry->im_context), priv->im_module);
+      break;
+
     case PROP_SCROLL_OFFSET:
     case PROP_CURSOR_POSITION:
     default:
@@ -1874,6 +1902,10 @@ gtk_entry_get_property (GObject         *object,
       g_value_set_boolean (value, priv->invisible_char_set);
       break;
 
+    case PROP_IM_MODULE:
+      g_value_set_string (value, priv->im_module);
+      break;
+
     case PROP_CAPS_LOCK_WARNING:
       g_value_set_boolean (value, priv->caps_lock_warning);
       break;
@@ -2259,6 +2291,8 @@ gtk_entry_finalize (GObject *object)
       entry->text = NULL;
     }
 
+  g_free (priv->im_module);
+
   G_OBJECT_CLASS (gtk_entry_parent_class)->finalize (object);
 }
 
index 54625757059e464e59595ba813d018bccc385ebd..f48fc84665d9f7943798723c1cdde48f98a012d2 100644 (file)
@@ -34,6 +34,7 @@ struct _GtkIMMulticontextPrivate
 {
   GdkWindow *client_window;
   GdkRectangle cursor_location;
+  gchar *context_id;
 
   guint use_preedit : 1;
   guint have_cursor_location : 1;
@@ -85,7 +86,6 @@ static gboolean gtk_im_multicontext_delete_surrounding_cb   (GtkIMContext      *
                                                             gint               n_chars,
                                                             GtkIMMulticontext *multicontext);
 
-static const gchar *user_context_id = NULL;
 static const gchar *global_context_id = NULL;
 
 G_DEFINE_TYPE (GtkIMMulticontext, gtk_im_multicontext, GTK_TYPE_IM_CONTEXT)
@@ -143,6 +143,7 @@ gtk_im_multicontext_finalize (GObject *object)
   
   gtk_im_multicontext_set_slave (multicontext, NULL, TRUE);
   g_free (multicontext->context_id);
+  g_free (multicontext->priv->context_id);
 
   G_OBJECT_CLASS (gtk_im_multicontext_parent_class)->finalize (object);
 }
@@ -226,19 +227,19 @@ gtk_im_multicontext_get_slave (GtkIMMulticontext *multicontext)
     {
       GtkIMContext *slave;
 
-      if (!global_context_id) 
+      g_free (multicontext->context_id);
+       
+      if (multicontext->priv->context_id)
+        multicontext->context_id = g_strdup (multicontext->priv->context_id);
+      else 
         {
-          if (user_context_id)
-            global_context_id = user_context_id;
-          else
+          if (!global_context_id)
             global_context_id = _gtk_im_module_get_default_context_id (multicontext->priv->client_window);
+          multicontext->context_id = g_strdup (global_context_id);
         }
-      slave = _gtk_im_module_create (global_context_id);
+      slave = _gtk_im_module_create (multicontext->context_id);
       gtk_im_multicontext_set_slave (multicontext, slave, FALSE);
       g_object_unref (slave);
-
-      g_free (multicontext->context_id);
-      multicontext->context_id = g_strdup (global_context_id);
     }
 
   return multicontext->slave;
@@ -335,8 +336,11 @@ gtk_im_multicontext_focus_in (GtkIMContext   *context)
    * for the new global context type.
    */
   if (multicontext->context_id == NULL || 
-      global_context_id == NULL ||
-      strcmp (global_context_id, multicontext->context_id) != 0)
+      (multicontext->priv->context_id != NULL &&
+       strcmp (multicontext->priv->context_id, multicontext->context_id) != 0) ||
+      (multicontext->priv->context_id == NULL &&
+       (global_context_id == NULL ||
+        strcmp (global_context_id, multicontext->context_id) != 0)))
     gtk_im_multicontext_set_slave (multicontext, NULL, FALSE);
 
   slave = gtk_im_multicontext_get_slave (multicontext);
@@ -494,11 +498,7 @@ activate_cb (GtkWidget         *menuitem,
     {
       const gchar *id = g_object_get_data (G_OBJECT (menuitem), "gtk-context-id");
 
-      gtk_im_context_reset (GTK_IM_CONTEXT (context));
-      
-      user_context_id = id;
-      global_context_id = NULL;
-      gtk_im_multicontext_set_slave (context, NULL, FALSE);
+      gtk_im_multicontext_set_context_id (context, id);
     }
 }
 
@@ -543,7 +543,7 @@ gtk_im_multicontext_append_menuitems (GtkIMMulticontext *context,
   
   system_context_id = _gtk_im_module_get_default_context_id (context->priv->client_window);
   system_menuitem = menuitem = gtk_radio_menu_item_new_with_label (group, C_("input method menu", "System"));
-  if (!user_context_id)
+  if (!context->priv->context_id)
     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem), TRUE);
   group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menuitem));
   g_object_set_data (G_OBJECT (menuitem), I_("gtk-context-id"), NULL);
@@ -616,8 +616,8 @@ gtk_im_multicontext_append_menuitems (GtkIMMulticontext *context,
       menuitem = gtk_radio_menu_item_new_with_label (group,
                                                     translated_name);
       
-      if ((user_context_id &&
-           strcmp (contexts[i]->context_id, user_context_id) == 0))
+      if ((context->priv->context_id &&
+           strcmp (contexts[i]->context_id, context->priv->context_id) == 0))
         gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem), TRUE);
 
       if (strcmp (contexts[i]->context_id, system_context_id) == 0)
@@ -661,6 +661,28 @@ gtk_im_multicontext_get_context_id (GtkIMMulticontext *context)
   return context->context_id;
 }
 
+/**
+ * gtk_im_multicontext_set_context_id:
+ * @context: a #GtkIMMulticontext
+ * @context_id: the id to use 
+ *
+ * Sets the context id for @context.
+ *
+ * This causes the currently active slave of @context to be
+ * replaced by the slave corresponding to the new context id.
+ *
+ * Since: 2.16
+ */
+void
+gtk_im_multicontext_set_context_id (GtkIMMulticontext *context,
+                                    const char        *context_id)
+{
+  gtk_im_context_reset (GTK_IM_CONTEXT (context));
+  g_free (context->priv->context_id);
+  context->priv->context_id = g_strdup (context_id);
+  gtk_im_multicontext_set_slave (context, NULL, FALSE);
+}
+
 
 #define __GTK_IM_MULTICONTEXT_C__
 #include "gtkaliasdef.c"
index 9e444cb00a35b1011310198e845927da9f5c5faa..951ddae266e976be297690b7d5829dc7392d5e1b 100644 (file)
@@ -70,7 +70,9 @@ void          gtk_im_multicontext_append_menuitems (GtkIMMulticontext *context,
                                                    GtkMenuShell      *menushell);
 const char  * gtk_im_multicontext_get_context_id   (GtkIMMulticontext *context);
 
-
+void          gtk_im_multicontext_set_context_id   (GtkIMMulticontext *context,
+                                                    const char        *context_id);
 G_END_DECLS
 
 #endif /* __GTK_IM_MULTICONTEXT_H__ */
index dc8126099c7d48b8d02fcc6b0ba538516b5cf11c..959721f53c48e92859d93b04a560447e42ee186a 100644 (file)
@@ -108,6 +108,7 @@ struct _GtkTextViewPrivate
 {
   guint blink_time;  /* time in msec the cursor has blinked since last user event */
   guint im_spot_idle;
+  gchar *im_module;
 };
 
 
@@ -156,7 +157,8 @@ enum
   PROP_CURSOR_VISIBLE,
   PROP_BUFFER,
   PROP_OVERWRITE,
-  PROP_ACCEPTS_TAB
+  PROP_ACCEPTS_TAB,
+  PROP_IM_MODULE
 };
 
 static void gtk_text_view_destroy              (GtkObject        *object);
@@ -661,6 +663,24 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                                                         TRUE,
                                                         GTK_PARAM_READWRITE));
 
+   /**
+    * GtkTextView:im-module:
+    *
+    * Which IM module should be used for this widget.
+    *
+    * Setting this to a non-%NULL value overrides the
+    * system-wide IM module setting. See #GtkSettings:gtk-im-module
+    *
+    * Since: 2.16
+    */
+   g_object_class_install_property (gobject_class,
+                                    PROP_IM_MODULE,
+                                    g_param_spec_string ("im-module",
+                                                         P_("IM module"),
+                                                         P_("Which IM module should be used"),
+                                                         NULL,
+                                                         GTK_PARAM_READWRITE));
+
   /*
    * Style properties
    */
@@ -2845,8 +2865,10 @@ static void
 gtk_text_view_finalize (GObject *object)
 {
   GtkTextView *text_view;
+  GtkTextViewPrivate *priv;
 
   text_view = GTK_TEXT_VIEW (object);
+  priv = GTK_TEXT_VIEW_GET_PRIVATE (text_view);
 
   g_assert (text_view->buffer == NULL);
 
@@ -2879,6 +2901,8 @@ gtk_text_view_finalize (GObject *object)
 
   g_object_unref (text_view->im_context);
 
+  g_free (priv->im_module);
+
   G_OBJECT_CLASS (gtk_text_view_parent_class)->finalize (object);
 }
 
@@ -2889,8 +2913,10 @@ gtk_text_view_set_property (GObject         *object,
                            GParamSpec      *pspec)
 {
   GtkTextView *text_view;
+  GtkTextViewPrivate *priv;
 
   text_view = GTK_TEXT_VIEW (object);
+  priv = GTK_TEXT_VIEW_GET_PRIVATE (text_view);
 
   switch (prop_id)
     {
@@ -2950,6 +2976,13 @@ gtk_text_view_set_property (GObject         *object,
       gtk_text_view_set_accepts_tab (text_view, g_value_get_boolean (value));
       break;
       
+    case PROP_IM_MODULE:
+      g_free (priv->im_module);
+      priv->im_module = g_strdup (g_value_get_string (value));
+      if (GTK_IS_IM_MULTICONTEXT (text_view->im_context))
+        gtk_im_multicontext_set_context_id (GTK_IM_MULTICONTEXT (text_view->im_context), priv->im_module);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -2963,8 +2996,10 @@ gtk_text_view_get_property (GObject         *object,
                            GParamSpec      *pspec)
 {
   GtkTextView *text_view;
+  GtkTextViewPrivate *priv;
 
   text_view = GTK_TEXT_VIEW (object);
+  priv = GTK_TEXT_VIEW_GET_PRIVATE (text_view);
 
   switch (prop_id)
     {
@@ -3024,6 +3059,10 @@ gtk_text_view_get_property (GObject         *object,
       g_value_set_boolean (value, text_view->accepts_tab);
       break;
       
+    case PROP_IM_MODULE:
+      g_value_set_string (value, priv->im_module);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;